import React, {
  useState,
  forwardRef,
  useImperativeHandle,
  useCallback,
  useRef,
  useEffect,
  useMemo
} from 'react';
import { Button, Drawer, ConfigProvider } from 'antd';
import { connect, mapProps, observer } from '@formily/react';
import { GlobalRegistry } from '@inbiz/core';
import { TextWidget, getMessage, } from '@inbiz/react';
import BizBody from '@inbiz/basic/BizBody';
import LangProvider from '@inbiz/basic/container';
import { InbizIcon, useEvents,h5Utils, singleTimeOut } from '@inbiz/utils';
import SearchView from './components/SearchView'; // 视图
import SmallPanelView from './components/SmallPanelView'
import { SearchPropsProvider } from '../../store';
import { StateType } from '../../store/searchPropsContext';
import { useViewType } from '../../store/hooks/useViewType';
import { ISearchResultData, useJumpResult } from '../../store/hooks/useJumpResult';
import { useSearchUIState } from '../../store/hooks/useSearchUIState';
import { useSearchUIDispatch } from '../../store/hooks/useSearchUIDispatch';
import { useConfigEventsApi } from '../../store/hooks/useSearchPropsState';
import { useSearchResultPage } from '../../store/hooks/useSearchResultPage';
import { useTabsConfig } from '../../store/hooks/useTabsConfig';
import api from './api';
import { defaultProps } from '../../designer/schema';
import zhCN from './locales/zh-CN';
import enUS from './locales/en-US';
import jaJP from './locales/ja-JP';
import antdZhCN from 'antd/lib/locale/zh_CN';

import './style.less';
import './common.less';

export type IProps = typeof defaultProps & { prefixCls: string };

export interface SearchEngineProps {
  /**
   * @description 类型
   * @default primary
   */
  type?: string;
  /**
   * @description 扩展样式名
   * @default button
   */
  className?: string;
  /**
   * @description 视图类型
   * @default 内嵌视图
   */
  viewType: string;
  tabsConfig: Array<any>;
  boxHeight?: string;
  style?: CSSStyleSheet;
  inTitle: {
    status: boolean;
    value: string;
  };
  inIcon: {
    type: string;
  };
  icon: {
    type: string;
    size: string;
    color: string;
  };
  placeholderWeb: string;
  callBackEvents: {
    onLoad?: () => void;
    // 搜索前，修改搜索数据
    onBeforeSearch?: <T extends ISearchResultData>(
      params: any,
      searchData: T,
    ) => Promise<T | false>; // 返回false 不搜索
    // 打开关联页面前, 添加url参数
    onBeforeOpenPage?: <T extends string>(url: T, data: Object) => Promise<T> | T;
    // 搜索历史
    onHistoryParams?: <T>(params: T) => Promise<T>;
    onHistory?: (params: object) => Promise<object>;
    onHistoryData?: <T>(data: T, params: unknown) => Promise<T>;
    //搜索推荐参数,
    onSearchKeyWordParams?: <T>(params: T) => Promise<T>;
    onSearchKeyWord?: (params: object) => Promise<object>;
    onSearchKeyWordData?: <T>(data: T, params: unknown) => Promise<T>;
    // 热门推荐
    onHotWordParams?: <T>(params: T) => Promise<T>;
    onHotWord?: (params: object) => Promise<object>;
    onHotWordData?: <T>(data: T, params: unknown) => Promise<T>;
    onCustomClear?: () => void
  };
}

const PreviewSearchMain = observer((props: StateType) => {
  const { ref } = props
  const viewType = useViewType();
  const { configEvents } = useConfigEventsApi();
  const [drawerHeight, $drawerHeight] = useState(550); // 抽屉的高度【默认500 有高级搜索的550】
  const [historyVisible, $historyVisible] = useState(false); // 历史搜索显示
  const { visibleDrawer, showGraph } = useSearchUIState();
  const updateState = useSearchUIDispatch();
  const tabsConfig = useTabsConfig();
  const placeholderText = getMessage(props.placeholderWeb);
  const [customPlaceholderText, $customPlaceholderText] = useState(placeholderText)
  const [customFolderId, $customFolderId] = useState('')
  const [searchMessage, $searchMessage] = useState({})
  // 下拉面板
  const [visible, $visible] = useState(false);
  // 小视图中切换视图样式
  const [showOriginSearch, $showOriginSearch] = useState(false)
  
  useEffect(() => {
    configEvents.current.onLoad?.();
  }, []);
  useEffect(() => {
    $customPlaceholderText(getMessage(props.placeholderWeb))
  }, [GlobalRegistry.getDesignerLanguage()])

  const showDrawer = () => {
    updateState({ visibleDrawer: true });
  };

  // 	抽屉取消事件
  const onDrawerClose = useCallback(() => {
    updateState({ visibleDrawer: false });
  }, []);

  const setHistoryVisible = (val: any) => {
    $historyVisible(val);
  };

  const resetSearchMessage = () => {
    $customPlaceholderText(getMessage('SearchEngine.search'))
    $customFolderId('')
    $searchMessage({})
  }
  // 大面板视图传参
  const largePanelViewProps = {
    drawerHeight: drawerHeight,
    historyVisible: historyVisible,
    onDrawerClose: onDrawerClose,
    onHistoryVisible: setHistoryVisible,
    customPlaceholderText,
    customFolderId,
    resetSearchMessage,
    searchMessage,
    $customPlaceholderText,
    visible, $visible,
    showOriginSearch, $showOriginSearch
  };
  const jumpResultRef = useRef(useJumpResult());
  jumpResultRef.current = useJumpResult();

  const updateUIState = useSearchUIDispatch();
  const saveSearchData = (params: any) => {
    const state = {};
    for (let i in params) {
      if (params[i]) state[i] = params[i];
    }
    updateUIState(state);
  };

  // 对外暴露
  useImperativeHandle(
    ref,
    () => api(configEvents, props, {
      updateState,
      jumpResultRef,
      saveSearchData,
      setbreadcrumbData: (data: any) => {
        if (data?.title) {
          const fromIn = getMessage('SearchEngine.fromIn')
          const searchIn = getMessage('SearchEngine.searchIn')
          $customPlaceholderText(`${fromIn}"${data.title}"${searchIn}`)
          $customFolderId(data.id)
          $searchMessage(data)
        } else {
          resetSearchMessage()
        }
      },
      setshowTeam: (bool: boolean) => {
        updateUIState({
          showTeam: bool
        });
      },
      setshowPerson: (bool: boolean) => {
        updateUIState({
          showPerson: bool
        });
      },
    }),
    [],
  );
  useEffect(() => {
    const find = tabsConfig.find((item) => item.isShow);

    updateUIState({
      selectShowTab: find
    });
  }, [tabsConfig, updateUIState]);

  /***** 处理缓存数据 BEGIN *****/
  // 获取第一次的搜索数据
  const firstSearchEngineData = useMemo(() => {
    //@ts-ignore
    let storage = localStorage.getItem('_searchEngineStatus');
    if (storage) {
      sessionStorage.setItem('_searchEngineStatus', storage);
      setTimeout(() => {
        localStorage.removeItem('_searchEngineStatus');
      }, 0);
    } else {
      storage = sessionStorage.getItem('_searchEngineStatus');
    }

    const searchEngineData = storage ? JSON.parse(storage) : null;
    if (searchEngineData?.selectShowTab) {
      const find = tabsConfig.find((item) => item.guid == searchEngineData.selectShowTab.guid);
      if (find) {
        searchEngineData.selectShowTab.searchMode = find.searchMode
        searchEngineData.selectShowTab.advancedSearch = find.advancedSearch
        searchEngineData.selectShowTab.advancedSearchStyle = find.advancedSearchStyle
        searchEngineData.selectShowTab.quikSearchTemplate = find.quikSearchTemplate
        searchEngineData.selectShowTab.filepath = find.filepath
        searchEngineData.selectShowTab.keywordAtlas = find.keywordAtlas
        searchEngineData.selectShowTab.imgSearchImg = find.imgSearchImg
      }
    }
    return searchEngineData;
  }, []);

  useEffect(() => {
    if (firstSearchEngineData) {
      
      updateUIState({
        ...firstSearchEngineData,
        keyword:
          typeof firstSearchEngineData['keyword'] === 'string' || typeof firstSearchEngineData['KeyWord'] === 'string'
            ? firstSearchEngineData['keyword'] || firstSearchEngineData['KeyWord']
            : '',
      });
    }
  }, [firstSearchEngineData, updateUIState]);
  /***** 处理缓存数据 END *****/

  useEffect(() => {
    if (props.inbiz.browser.designer) {
      return;
    }
    // // 搜索组件在页面内
    // props.inbiz.on('search._result', searchEngineDataChange);
    // 搜索组件在全局布局中
    if (props.inbiz.global) {
      props.inbiz.global.on('search', (params1, params2, params3, params4) => {
        let data = {}, resultId
        if (params3.IndexName) {
          resultId = params2
          data = params3
        } else if (params4.IndexName) {
          resultId = params3
          data = params4
        }
        if (props.controlId != resultId && data?.IndexName?.length) {
          updateUIState({
            keyword: data?.KeyWord
          })
        }
      });
    }
    return () => {
      if (props.inbiz.browser.designer) {
        return;
      }
      if (props.inbiz.global) {
        props.inbiz.global.off('search');
      }
      // props.inbiz.off('search._result');

    };
  }, []);

  useEffect(() => {
    updateUIState({
      customFolderId
    })
  }, [customFolderId])

  const handleClose = (e) => {
    clearTimeout(window[`inbiz-search-send${props.controlId}`]);
    singleTimeOut(() => {
      h5Utils.inbizPageEvent.emit(props.controlId);
    }, 0, `inbiz-search-send${props.controlId}`)
  }


  const isclose = useRef(false);
  /**
   * 控制下拉面板的显示隐藏
   * 通过h5Utils来监听事件
   * 关闭面板在打开面板之前,所以在所有需要打开面板的地方触发打开,监听的click事件先执行,打开的监听后执行就覆盖了关闭操作
   */
  useEffect(() => {
    h5Utils.inbizPageEvent.off(props.controlId);

    h5Utils.inbizPageEvent.on(props.controlId, (isPre) => {

      if (isPre) {
        isclose.current = true;
      } else {
        if (isclose.current === true) {
          return
        }
      }
      singleTimeOut(() => {
        if (isPre) {
          isclose.current = false;
          return
        }
        updateUIState({
          showSearchResultPanel: false,
          showGraph: false
        });
        $visible(false)
        
        if (showOriginSearch && !isPre) {
          $showOriginSearch(false)
        }
      }, 50, `inbiz-search-recieve${props.controlId}`)
    });
    document.addEventListener('click', handleClose)
    return () => {
      document.removeEventListener('click', handleClose)
    }
  }, [showOriginSearch])


  return (
    <div style={{ height: props.boxHeight }} className="search-engine">
      <BizBody {...props} style={{ ...props.style, overflow: 'inherit' }}>
        {viewType == 'largePanelView' &&
          <div>
            {props.inTitle?.status && props.inTitle?.value ? (
              <Button
                className="largePanel_btn"
                onClick={showDrawer}
                icon={
                  props.inIcon === undefined ? (
                    <InbizIcon type="icon-inbiz_basic-search" /> //该行为升级兼容
                  ) : (
                    props.inIcon?.type && <InbizIcon type={props.inIcon.type} />
                  )
                }
              >
                {props.inTitle?.status && props.inTitle?.value && (
                  <TextWidget>{props.inTitle?.value}</TextWidget>
                )}
              </Button>
            ) : (
              <div className="largePanel_iconBox" onClick={showDrawer}>
                {props.inIcon === undefined ? (
                  <InbizIcon type="icon-inbiz_basic-search" /> //该行为升级兼容
                ) : (
                  props.inIcon?.type && (
                    <InbizIcon type={props.inIcon.type} style={{ fontSize: 20 }} />
                  )
                )}
              </div>
            )}
            <Drawer
              title=""
              placement="top" // 	抽屉的方向
              height={showGraph ? 650 : drawerHeight}
              onClose={onDrawerClose} // 点击遮罩层或左上角叉或取消按钮的回调
              visible={visibleDrawer}
              closable={false}
              className="large-search-drawer"
              zIndex={10}
              push={false}
            >
              <SearchView {...props} {...largePanelViewProps} />
            </Drawer>
          </div>}
        {viewType == 'inlineView' && <SearchView {...props} {...largePanelViewProps} />}
        {viewType == 'smallPanelView' && <SmallPanelView {...props} {...largePanelViewProps} />}
      </BizBody>
    </div>
  );
}, {
  forwardRef: true
});

const PreviewSearchEngine = forwardRef(
  (props: StateType & { callBackEvents: SearchEngineProps['callBackEvents'] }, ref: any) => {
    const [configEvents] = useEvents(props.callBackEvents);

    return (
      <LangProvider
        locales={{
          'zh-CN': zhCN,
          'ja-JP': enUS,
          'en-US': jaJP,
        }}
      >
        <ConfigProvider locale={antdZhCN}>
          <SearchPropsProvider {...props} configEvents={configEvents}>
            <PreviewSearchMain {...props} ref={ref} />
          </SearchPropsProvider>
        </ConfigProvider>
      </LangProvider>
    );
  },
);

export default connect(
  PreviewSearchEngine,
  mapProps({}, function (props, field) {
    return { ...props, boxHeight: field.decoratorProps?.style?.height };
  }),
);
